﻿/*
Audica Uploader - application for convenient uploading to various file hostings
Copyright (C) 2011-2012 Makarov Andrey (Winand)

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef SCRIPTCLASSES_H
#define SCRIPTCLASSES_H
#include <QtNetwork>
#include <QtScript>
#include <QObject>
#include "zhttpmultipart.h"
#include "charsetter.h"

typedef QObject* (*loadScriptPlugin)();
struct scriptplugin {
    loadScriptPlugin instProc;
    int version;
    QString description;
};

//class to pass upload results from script to app
class UploadResult : public QObject
{
Q_OBJECT
public:
    explicit UploadResult(QObject* parent) : QObject(parent) { }
    QList<QString> urls;
    QList<QString> descriptions;
    QString fail_desc; //when failed this string is not empty
    bool hasFailed() {
        return !fail_desc.isEmpty();
    }
public slots:
    void appendUrl(QString url, QString description) {
        urls.append(url);
        descriptions.append(description);
    }
    void failed(QString description) {
        if(description.length())
            fail_desc = description;
        else fail_desc = tr("Failed to upload");
    }
};

class ScriptRequestData : public Charsetter, public QNetworkRequest
{
Q_OBJECT
public:
    explicit ScriptRequestData(QObject* parent) : Charsetter(parent) { }
public slots:
    void setHeader(QString name, QString value) {
        setRawHeader(strConv(name, cs_names), strConv(value, cs_values));
    }
    void setUrl(QString url) {
        QNetworkRequest::setUrl(QUrl(url));
    }
    QString urlGetParam(QString param) {
        return url().queryItemValue(param);
    }
};

class ScriptWebRequest : public QObject
{
Q_OBJECT
public:
    explicit ScriptWebRequest(QNetworkAccessManager* manager, QObject *parent);
private:
    enum RequestType {
        RT_GET = 101,
        RT_POST
    };
    void resetReply();
    QNetworkAccessManager* netw;
    QNetworkReply* reply;
    QUrl lastRedirectUrl;
    //get/post request
    void abstract_request(RequestType type, QNetworkRequest request, QHttpMultiPart* body = 0);
private slots:
    void reply_finished();
    void uploadProgress(qint64 bytesSent, qint64 bytesTotal);
    void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
public slots:
    bool isRunning();
    /*void get(ScriptRequestData* request);*/
    void get(const QString url);
    void post(ScriptRequestData* request, ZHttpMultiPart* body);
    QString getContents();
    QString getHeader(const QString key); //TODO: /key/ is converted to utf8, not ascii or latin1
    QString getUrl();
signals:
    void requestFinished();
    void resetTimeout(int waittime);
    void progress(qint64 bytes, qint64 total);
};

class ScriptCoreClass : public QObject
{
Q_OBJECT
public:
    explicit ScriptCoreClass(QScriptEngine* engine_s, QObject* parent);
    void setPluginsList(QMap<QString, scriptplugin>* plugins);
    void setFilepath(const QString path) {
           private_file = path;
    }
private:
    QScriptEngine* engine;
    QMap<QString, scriptplugin>* scriptPlugins;
    QString private_file;
private slots:
public slots:
    QString filepath() {
        return private_file;
    }
    bool checkObjectType(const QString type);
    bool newObject(const QString name, const QString type);
    bool deleteObject(const QString name);
    void alert(const QString str);
    void failed(const QString description);
    void succeeded(const QString description);
    QNetworkAccessManager* getAccessManager();
    /*void writeToFile(const QByteArray &str);*/
signals:
    void resetTimeout(int waittime);
    void progress(qint64 bytes, qint64 total);
    void setStatusText(const QString text);
    void finished(UploadResult* res);
};

#endif // SCRIPTCLASSES_H
